package util

import (
	"fmt"
)

func InSlice(s string, ss []string) bool {
	for _, v := range ss {
		if s == v {
			return true
		}
	}
	return false
}

func KeyValueMap(slice []string) (value2index map[string]int, index2value map[int]string) {
	value2index = make(map[string]int)
	index2value = make(map[int]string)
	for i, v := range slice {
		value2index[v] = i + 1
		index2value[i+1] = v
	}
	return
}

// 判断某一年是不是闰年
func isLeap(year int) bool {
	return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}

// 判断某一天是星期几
// 蔡勒公式: w = y + [y / 4] + [c / 4] - 2 * c + [26 * (m + 1) / 10] + d - 1
// w:星期、c:世纪 - 1、y:年份后两位、m:月份、d:日、[]:取整
// m大于等于3, 小于等于14, 即在蔡勒公式中, 某年的1、2月要看作上一年的13、14月来计算, 比如2003年1月1日要看作2002年的13月1日来计算
func WhichDay(year, month, day int) string {
	var y, m, c int
	if month >= 3 {
		m = month
		y = year % 100
		c = year / 100
	} else {
		m = month + 12
		y = (year - 1) % 100
		c = (year - 1) / 100
	}
	week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
	if week < 0 {
		week = 7 - (-week)%7
	} else {
		week = week % 7
	}
	return weekday[week]
}

// 判断某一天是不是工作日
func isWorkDay(year, month, day int, date string) bool {
	if InSlice(date, compensatoryLeave) {
		return true
	}
	if InSlice(date, statutoryHoliday) {
		return false
	}
	w := WhichDay(year, month, day)
	switch w {
	case "周一", "周二", "周三", "周四", "周五":
		return true
	}
	return false
}

// 生成2020年、2021年所有日期以及工作日
func DayGenerator() ([]string, []string) {
	allDaySlice := make([]string, 0)
	workDaySlice := make([]string, 0)
	for year := 2020; year < 2022; year++ {
		for month := 1; month < 13; month++ {
			switch month {
			case 1, 3, 5, 7, 8, 10, 12:
				for day := 1; day < 32; day++ {
					monthFormat := fmt.Sprintf("%d", month)
					dayFormat := fmt.Sprintf("%d", day)
					if len(monthFormat) == 1 {
						monthFormat = "0" + monthFormat
					}
					if len(dayFormat) == 1 {
						dayFormat = "0" + dayFormat
					}
					date := fmt.Sprintf("%d%s%s", year, monthFormat, dayFormat)
					allDaySlice = append(allDaySlice, date)
					if isWorkDay(year, month, day, date) {
						workDaySlice = append(workDaySlice, date)
					}
				}
			case 4, 6, 9, 11:
				for day := 1; day < 31; day++ {
					monthFormat := fmt.Sprintf("%d", month)
					dayFormat := fmt.Sprintf("%d", day)
					if len(monthFormat) == 1 {
						monthFormat = "0" + monthFormat
					}
					if len(dayFormat) == 1 {
						dayFormat = "0" + dayFormat
					}
					date := fmt.Sprintf("%d%s%s", year, monthFormat, dayFormat)
					allDaySlice = append(allDaySlice, date)
					if isWorkDay(year, month, day, date) {
						workDaySlice = append(workDaySlice, date)
					}
				}
			case 2:
				if isLeap(year) {
					for day := 1; day < 30; day++ {
						monthFormat := fmt.Sprintf("%d", month)
						dayFormat := fmt.Sprintf("%d", day)
						if len(monthFormat) == 1 {
							monthFormat = "0" + monthFormat
						}
						if len(dayFormat) == 1 {
							dayFormat = "0" + dayFormat
						}
						date := fmt.Sprintf("%d%s%s", year, monthFormat, dayFormat)
						allDaySlice = append(allDaySlice, date)
						if isWorkDay(year, month, day, date) {
							workDaySlice = append(workDaySlice, date)
						}
					}
				} else {
					for day := 1; day < 29; day++ {
						monthFormat := fmt.Sprintf("%d", month)
						dayFormat := fmt.Sprintf("%d", day)
						if len(monthFormat) == 1 {
							monthFormat = "0" + monthFormat
						}
						if len(dayFormat) == 1 {
							dayFormat = "0" + dayFormat
						}
						date := fmt.Sprintf("%d%s%s", year, monthFormat, dayFormat)
						allDaySlice = append(allDaySlice, date)
						if isWorkDay(year, month, day, date) {
							workDaySlice = append(workDaySlice, date)
						}
					}
				}
			}
		}
	}
	return allDaySlice, workDaySlice
}

var allDaySlice, workDaySlice = DayGenerator()
var AllDayValue2Index, AllDayIndex2Value = KeyValueMap(allDaySlice)
var WorkDayValue2Index, WorkDayIndex2Value = KeyValueMap(workDaySlice)
